home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / fstream.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  31.3 KB  |  1,420 lines

  1. #ifndef __FSTREAM_CC
  2. #define __FSTREAM_CC
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * fstream.cc - Definition for the Standard Library file streams
  8.  *
  9.  * $Id: fstream.cc,v 1.79 1996/09/27 07:04:46 philippe Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  14.  * ALL RIGHTS RESERVED *
  15.  * The software and information contained herein are proprietary to, and
  16.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  17.  * intends to preserve as trade secrets such software and information.
  18.  * This software is furnished pursuant to a written license agreement and
  19.  * may be used, copied, transmitted, and stored only in accordance with
  20.  * the terms of such license and with the inclusion of the above copyright
  21.  * notice.  This software and information or any other copies thereof may
  22.  * not be provided or otherwise made available to any other person.
  23.  *
  24.  * Notwithstanding any other lease or license that may pertain to, or
  25.  * accompany the delivery of, this computer software and information, the
  26.  * rights of the Government regarding its use, reproduction and disclosure
  27.  * are as set forth in Section 52.227-19 of the FARS Computer
  28.  * Software-Restricted Rights clause.
  29.  * 
  30.  * Use, duplication, or disclosure by the Government is subject to
  31.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  32.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  33.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  34.  * P.O. Box 2328, Corvallis, Oregon 97339.
  35.  *
  36.  * This computer software and information is distributed with "restricted
  37.  * rights."  Use, duplication or disclosure is subject to restrictions as
  38.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  39.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  40.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  41.  * then the "Alternate III" clause applies.
  42.  *
  43.  **************************************************************************/
  44.  
  45. #ifndef _RWSTD_NO_NEW_HEADER
  46. #include <cstdio>
  47. #else
  48. #include <stdio.h>
  49. #endif
  50.  
  51.  
  52. #ifndef _RWSTD_NO_NAMESPACE
  53. namespace std {
  54. #endif
  55.  
  56. //
  57. // Work-around for Borland problem.
  58. //
  59. #ifdef __BORLANDC__
  60. template <class T>
  61. void __io_initialize (T& t, T val) { t = val; }
  62. #endif
  63.  
  64. /*
  65.  *
  66.  *
  67.  * class basic_filebuf
  68.  *
  69.  *
  70.  */
  71.  
  72. /*
  73.  * basic_filebuf()
  74.  */
  75.  
  76. template<class charT, class traits>
  77. basic_filebuf<charT, traits>::basic_filebuf()
  78. : basic_streambuf<charT, traits>()
  79. , file_(-1)
  80. , data_(0)
  81. , read_buff_(false)
  82. , write_buff_(false)
  83. , last_numb_read_(0)
  84. , __rwBufferSize(512)
  85. , absolute_pos(0)
  86. {
  87.   state_beg = new state_t;
  88.   state_end = new state_t;
  89. }
  90.  
  91. /*
  92.  * basic_filebuf(int)
  93.  */
  94.  
  95. template<class charT, class traits>
  96. basic_filebuf<charT, traits>::basic_filebuf(int fd)
  97. : basic_streambuf<charT, traits>()
  98. , file_(fd)
  99. , read_buff_(false)
  100. , write_buff_(false)
  101. , last_numb_read_(0)
  102. , __rwBufferSize(512)
  103. , absolute_pos(0)
  104. {
  105.   data_ = new char_type[__rwBufferSize+1];
  106.   state_beg = new state_t;
  107.   state_end = new state_t;
  108.  
  109.   if ( fd == 0 )
  110.    basic_streambuf<charT,traits>::mode_ = ios_base::in;
  111.   else
  112.   {
  113.     if ( fd < 3 )
  114.      basic_streambuf<charT,traits>::mode_ = ios_base::out;
  115.   }
  116.  
  117. }
  118.  
  119.  
  120. /*
  121.  * ~basic_filebuf()
  122.  */
  123.  
  124. template<class charT, class traits>
  125. basic_filebuf<charT, traits>::~basic_filebuf()
  126. {
  127.   close();
  128.   delete state_beg;
  129.   delete state_end;
  130. }
  131.  
  132. /*
  133.  * bool is_open() const
  134.  */
  135.  
  136. template<class charT, class traits>
  137. bool basic_filebuf<charT, traits>::is_open() const
  138. {
  139.   return !(file_ == -1);
  140. }
  141.  
  142. /*
  143.  * basic_filebuf *open(int fd)
  144.  *
  145.  * fstream compatibility
  146.  */
  147.  
  148.  
  149. template<class charT, class traits>
  150. basic_filebuf<charT, traits> *
  151. basic_filebuf<charT, traits>::
  152. open(int fd )
  153. {   
  154.   if(file_ != -1)
  155.      return 0;
  156.  
  157.   this->streambuf_init(false); 
  158.  
  159.   file_           = fd;
  160.   read_buff_      = false;
  161.   write_buff_     = false;
  162.   last_numb_read_ = 0; 
  163.  
  164.   delete [] data_;
  165.  
  166.   data_ = new char_type[__rwBufferSize+1];
  167.  
  168.   if ( fd == 0 )
  169.    basic_streambuf<charT,traits>::mode_ = ios_base::in;
  170.   else
  171.   {
  172.     if ( fd < 3 )
  173.      basic_streambuf<charT,traits>::mode_ = ios_base::out;
  174.   }
  175.  
  176.   return this;
  177. }
  178.  
  179.  
  180.  
  181. /*
  182.  * basic_filebuf *open(const char *, ios_base::openmode, long )
  183.  *
  184.  * opens a file and allocates a buffer
  185.  */
  186.  
  187.  
  188. template<class charT, class traits>
  189. basic_filebuf<charT, traits> *
  190. basic_filebuf<charT, traits>::
  191. open(const char *s, ios_base::openmode mode, long protection)
  192. {
  193.   #if !defined(_RWSTD_NO_NAMESPACE) && !defined(_RWSTD_NO_NEW_HEADER)
  194.   using std::open;
  195.   #endif
  196.  
  197.   long    m;
  198.  
  199.   if ( mode & ios_base::ate )
  200.    m = (mode & (~ios_base::ate)) | ios_base::app;
  201.   else
  202.    m = mode;
  203.   
  204.   if(file_ != -1)
  205.      return 0;
  206.  
  207.   basic_streambuf<charT,traits>::mode_ = mode;
  208.  
  209.   this->streambuf_init(false);
  210.  
  211.   if(__rwOpenTable[m] == -1) 
  212.    return 0;
  213.  
  214.  #if !defined(_RWSTD_NO_NAMESPACE) && !defined(_RWSTD_NO_NEW_HEADER)
  215.    if((file_ = open(s, __rwOpenTable[m], protection)) == -1)
  216.  #else
  217.    if((file_ = ::open(s, __rwOpenTable[m], protection)) == -1)
  218.  #endif
  219.    return 0;
  220.  
  221.   delete [] data_;
  222.  
  223.   data_ = new char_type[__rwBufferSize+1];
  224.  
  225.   if(mode & ios_base::ate) {
  226.      if( (absolute_pos = lseek(file_, 0, SEEK_END))== -1  ) {
  227.         close();
  228.         delete [] data_;  
  229.         data_ = 0;
  230.                 file_=-1;
  231.         return 0;
  232.      }
  233.   }
  234.  
  235.     
  236.   return this;
  237. }
  238.  
  239. /*
  240.  * basic_filebuf *close()
  241.  *
  242.  * closes a file if one was already open.  Also deletes the
  243.  * data, if it was allocated
  244.  */
  245.  
  246. template<class charT, class traits>
  247. basic_filebuf<charT, traits> *
  248. basic_filebuf<charT, traits>::close()
  249. {
  250.   #if !defined(_RWSTD_NO_NAMESPACE) && !defined(_RWSTD_NO_NEW_HEADER)
  251.   using std::close;
  252.   #endif
  253.  
  254. delete state_beg;
  255. delete state_end;
  256. state_beg = new state_t;
  257. state_end = new state_t;
  258.  
  259. absolute_pos = 0;
  260.  
  261. if ( (file_ < 3)  && (file_ != -1) )
  262.  {
  263.     if ( write_buff_ )
  264.      overflow( traits::eof() );
  265.     read_buff_=false;
  266.     write_buff_=false;
  267.     last_numb_read_=0;
  268.     return this;
  269.  }
  270.    
  271.   if(file_ != -1) {          
  272.     if ( write_buff_ )
  273.      overflow( traits::eof() );
  274.     delete [] data_;
  275.     data_ = 0;
  276.     read_buff_=false;
  277.     write_buff_=false;
  278.     last_numb_read_=0;
  279.  
  280.   #if !defined(_RWSTD_NO_NAMESPACE) && !defined(_RWSTD_NO_NEW_HEADER)
  281.     if(close(file_) == -1)
  282.   #else
  283.     if(::close(file_) == -1)
  284.   #endif
  285.       return 0;
  286.  
  287.     file_ = -1;
  288.  
  289.     return this;
  290.   }
  291.  
  292.   return 0;          
  293. }
  294.  
  295. /*
  296.  * int showmanyc()
  297.  */
  298.  
  299. template<class charT, class traits>
  300. int
  301. basic_filebuf<charT, traits>::showmanyc()
  302.    if ( gptr() )
  303.     return (int)(egptr()-gptr());
  304.    
  305.    if ( pptr() && read_buff_ )
  306.         return (int)(epptr()-pptr());   
  307.  
  308.    return 0;
  309.  
  310. }
  311.  
  312.  
  313.  
  314. /*
  315.  * int_type overflow(int_type)
  316.  *
  317.  * this is called when the put pointer overruns the buffer.
  318.  * it should flush what was in the put buffer, and move the pointer
  319.  * back to the beginning
  320.  */
  321.  
  322. template<class charT, class traits>
  323. _TYPENAME basic_filebuf<charT, traits>::int_type
  324. basic_filebuf<charT, traits>::overflow(int_type c)
  325. {
  326.   long  count = pptr() - pbase();
  327.   bool   do_noconv;
  328.  
  329.   if(file_ == -1)        
  330.    return traits::eof();
  331.  
  332.   if ( (pptr()==0) && gptr() )
  333.    {
  334.       setp(eback(),eback()+__rwBufferSize);
  335.       pbump((int)(gptr()-eback()));
  336.       setg(0,0,0);
  337.       if ( pptr()<epptr() )
  338.        { 
  339.          if( !traits::eq_int_type(c,traits::eof()) ) 
  340.           {
  341.        sputc( traits::to_char_type(c) );
  342.        this->gbump(1);
  343.            write_buff_=true;
  344.            return traits::to_int_type(*pptr());
  345.          }
  346.        } 
  347.       count=  pptr() - pbase();
  348.    }
  349.  
  350.   if ( (pptr()==0) && (gptr()==0) )
  351.     setp(data_,data_+ __rwBufferSize);  
  352.  
  353.   write_buff_= false;
  354.  
  355.   if(count)
  356.    {        
  357.     #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  358.      do_noconv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  359.     #else
  360.      do_noconv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  361.     #endif
  362.       .always_noconv();
  363.  
  364.     if ( do_noconv )
  365.      {
  366.         if ( read_buff_ ) 
  367.          {
  368.            if ( lseek(file_, -last_numb_read_, SEEK_CUR) == -1 )
  369.             return traits::eof();
  370.          }
  371.         if((size_t)write(file_,(char *)pbase(), count*sizeof(charT))!= 
  372.                  count*sizeof(charT))
  373.          return traits::eof();
  374.      }
  375.     else
  376.      {
  377.       long size_to = count*sizeof(charT);
  378.       const charT *from_next =0;
  379.       char *to= new char[size_to];
  380.       char *to_next = 0;
  381.       codecvt_base::result conv_result;
  382.  
  383.       if ( read_buff_ )
  384.        {
  385.          if ( lseek(file_, -last_numb_read_, SEEK_CUR) == -1 )
  386.           return traits::eof();
  387.          else
  388.           {
  389.             state_t *tmp = state_beg;
  390.             state_beg = state_end;
  391.             state_end = tmp;
  392.           }
  393.        }
  394.  
  395.        *state_beg = *state_end;
  396.  
  397.     do {
  398.  
  399.        #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  400.         conv_result = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  401.        #else
  402.         conv_result = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  403.        #endif
  404.         .out(*state_end,pbase(),pptr(),from_next,
  405.                  to,to+size_to,to_next); 
  406.  
  407.       if ( conv_result == codecvt_base::noconv ) break;
  408.  
  409.       if (  (conv_result == codecvt_base::partial) || ( from_next != pptr() ) )
  410.        {
  411.          size_to *= 2;
  412.          char *to_bis = new char[size_to];
  413.          long diff_to = to_next - to;
  414.          memcpy(to_bis,to,diff_to);
  415.          delete [] to;
  416.          to = to_bis;
  417.          to_next = to + diff_to;
  418.        }
  419.  
  420.       }while( (conv_result == codecvt_base::partial) || ( from_next != pptr()));
  421.  
  422.      if ( conv_result==codecvt_base::error )
  423.       {
  424.          delete [] to;
  425.          return traits::eof();
  426.       }
  427.  
  428.      if (conv_result == codecvt_base::noconv) 
  429.       {
  430.        if((size_t)write(file_, (char*)pbase(), sizeof(charT)*count)
  431.           != sizeof(charT) * count)
  432.          {
  433.           delete [] to;
  434.           return traits::eof();              
  435.          }
  436.       } 
  437.      else 
  438.       {
  439.        if(write(file_, to, (to_next-to)) != (to_next-to))
  440.         {
  441.           delete [] to;
  442.           return traits::eof();                
  443.         }
  444.        }
  445.  
  446.       delete [] to;
  447.     }
  448.                 
  449.   }
  450.  
  451.   setp(data_, data_+__rwBufferSize);    
  452.   setg(0,0,0);               
  453.   read_buff_ = false;        
  454.   write_buff_= false; 
  455.  
  456.   absolute_pos = lseek(file_,0,SEEK_CUR);
  457.  
  458.   if( !traits::eq_int_type(c,traits::eof()) ) 
  459.    {
  460.      sputc(traits::to_char_type(c));
  461.      this->gbump(1);
  462.      write_buff_ = true;
  463.    }
  464.   else
  465.    setp(0,0);
  466.  
  467.   return traits::not_eof(c);
  468. }
  469.  
  470. /*
  471.  * int_type pbackfail(int_type)
  472.  */
  473.  
  474.  
  475. template<class charT, class traits>
  476. _TYPENAME basic_filebuf<charT, traits>::int_type
  477. basic_filebuf<charT, traits>::pbackfail(int_type c)
  478. {
  479.   if(file_ == -1)
  480.      return traits::eof();
  481.  
  482.   if ( (gptr()==0) && pptr() )
  483.    {
  484.       if ( read_buff_ )
  485.        setg(pbase(),pptr(),epptr());
  486.       else
  487.        setg(pbase(),pptr(),pptr()); 
  488.    }
  489.  
  490.   if ( (!traits::eq_int_type(c,traits::eof())) && (gptr()>eback()) )  {
  491.  
  492.                          if ( traits::eq(*(gptr()-1),traits::to_char_type(c)) ) 
  493.                                  {
  494.                                    this->gbump(-1);
  495.                                    return c;
  496.                                  }
  497.                                 else
  498.                                  {
  499.                                    if( basic_streambuf<charT,traits>::mode_ & ios_base::out )
  500.                                      {
  501.                                        this->gbump(-1);
  502.                                        *gptr()=traits::to_char_type(c);
  503.                                        return c;
  504.                                      }
  505.                                  }
  506.                  }    
  507.  
  508.   if ( (traits::eq_int_type(c,traits::eof())) && (gptr()>eback()) )  
  509.    { 
  510.      this->gbump(-1);
  511.      return traits::not_eof(c);
  512.    }
  513.                                                 
  514.   return traits::eof();
  515.  }
  516.  
  517. /*
  518.  * basic_streambuf<charT,traits>* setbuf(char_type*,streamsize)
  519.  */
  520.  
  521. template<class charT, class traits>
  522. basic_streambuf<charT, traits>*
  523. basic_filebuf<charT, traits>::setbuf(char_type *s, streamsize n)
  524. {
  525.  
  526.  if (n>0)
  527.  { 
  528.  
  529.   if ( file_ != -1 )
  530.    {
  531.      if ( !traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  532.        {
  533.           if ( s )
  534.            { 
  535.               delete [] data_;
  536.               __rwBufferSize = n-1; 
  537.               data_=s;
  538.            }
  539.           else
  540.            {
  541.               charT *tmp;
  542.               __rwBufferSize = n;  
  543.               tmp = new char_type[__rwBufferSize+1];
  544.               delete [] data_;
  545.               data_ = tmp;
  546.            }
  547.  
  548.           setp(0,0);    
  549.           setg(0,0,0);                         
  550.           read_buff_=false;
  551.           write_buff_=false;
  552.        }
  553.    }
  554.   else
  555.     {
  556.       if ( s )
  557.        {
  558.           __rwBufferSize = n-1;
  559.           data_ =s;
  560.           setp(0,0);    
  561.           setg(0,0,0);                        
  562.           write_buff_= false;
  563.           read_buff_ = false; 
  564.        }
  565.       else
  566.       __rwBufferSize = n;
  567.     }  
  568.  } 
  569.   return (basic_streambuf<charT,traits>*)(this); 
  570.   
  571. }
  572.  
  573.  
  574. /*
  575.  * int_type underflow()
  576.  *
  577.  * this is called when the get pointer "underflows" the buffer,
  578.  * or when there are no more "get" characters.
  579.  */
  580.  
  581. template<class charT, class traits>
  582. _TYPENAME basic_filebuf<charT, traits>::int_type
  583. basic_filebuf<charT, traits>::underflow()
  584. {
  585.   bool do_noconv;
  586.   long offset;
  587. #ifndef __BORLANDC__
  588.   offset = 0;
  589. #else
  590.   __io_initialize(offset,0L);
  591. #endif
  592.  
  593.   if(file_ == -1)
  594.     return traits::eof();
  595.  
  596.  
  597.   if ( (gptr()==0) && pptr() )
  598.    {
  599.       if ( read_buff_ )
  600.        setg(pbase(),pptr(),epptr());
  601.       else
  602.        setg(pbase(),pptr(),pptr());
  603.  
  604.       setp(0,0);
  605.    }
  606.  
  607.   if(gptr() && (gptr()<egptr()) ) return traits::to_int_type(*gptr());     
  608.  
  609.   if( ((write_buff_) && gptr() ) || ((write_buff_) && pptr() ) )
  610.     {
  611.          if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) ) 
  612.            return traits::eof();
  613.          setg(pbase(),pptr(),epptr());
  614.          setp(0,0);
  615.          write_buff_ = false; 
  616.     }                 
  617.  
  618.     absolute_pos = lseek(file_,0,SEEK_CUR);
  619.  
  620.     #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  621.       do_noconv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  622.     #else
  623.       do_noconv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  624.     #endif
  625.       .always_noconv();
  626.  
  627.     if ( do_noconv )
  628.      {
  629.       last_numb_read_ = read(file_, (char *)data_,__rwBufferSize*sizeof(charT));
  630.  
  631.       if( last_numb_read_ <= 0 ) 
  632.        { 
  633.          if ( write_buff_ ) overflow( traits::eof() );
  634.          write_buff_ = false;
  635.      setp(0,0);       
  636.          setg(0,0,0);
  637.          read_buff_=false;
  638.      return traits::eof();
  639.        }
  640.       else
  641.        offset = last_numb_read_/sizeof(charT);
  642.  
  643.      }
  644.     else
  645.      {
  646.       long from_size = __rwBufferSize*sizeof(charT);
  647.       const char *from_next =0;
  648.       char *from= new char[from_size];
  649.       charT *to_next = 0;
  650.       codecvt_base::result conv_result;
  651.  
  652.       last_numb_read_ = 0;
  653.       long new_numb_read;
  654.  
  655.  
  656.       do {
  657.            new_numb_read = read(file_, from+last_numb_read_
  658.                                 ,__rwBufferSize*sizeof(charT));
  659.  
  660.            last_numb_read_ += new_numb_read;
  661.  
  662.         if( last_numb_read_ <= 0 ) 
  663.             { 
  664.              if ( write_buff_ ) overflow( traits::eof() );
  665.              write_buff_ = false;
  666.          setp(0,0);       
  667.              setg(0,0,0);
  668.              read_buff_=false;
  669.          return traits::eof();
  670.            }
  671.  
  672.          if( new_numb_read <= 0 ) 
  673.           break;
  674.  
  675.        *state_beg = *state_end;
  676.  
  677.        #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  678.         conv_result = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  679.        #else
  680.         conv_result = use_facet(this->getloc(), (codecvt<charT,char,state_t>* )0)
  681.        #endif
  682.         .in(*state_end,from,from+last_numb_read_,from_next,data_,
  683.             data_+__rwBufferSize,to_next); 
  684.  
  685.          if ( (conv_result == codecvt_base::error) ||
  686.               (conv_result == codecvt_base::noconv) ) break;
  687.  
  688.          if (  (to_next != (data_ + __rwBufferSize) ) &&
  689.                 ( (size_t)new_numb_read == __rwBufferSize*sizeof(charT) ) )
  690.            {
  691.              from_size *= 2;
  692.              char *from_bis = new char[from_size];
  693.              long diff_from = from_next - from;
  694.              memcpy(from_bis,from,last_numb_read_);
  695.              delete [] from;
  696.              from = from_bis;
  697.              from_next = from + diff_from;
  698.            }
  699.  
  700.           } while ( (to_next != (data_ + __rwBufferSize) ) &&
  701.                     ( (size_t)new_numb_read == __rwBufferSize*sizeof(charT) ) ); 
  702.                
  703.        if ( (conv_result==codecvt_base::error) ||
  704.             (conv_result==codecvt_base::partial) )
  705.        {
  706.          delete [] from;
  707.          return traits::eof();
  708.        } 
  709.       else 
  710.        {
  711.          if (conv_result==codecvt_base::noconv)
  712.           {
  713.             memcpy((char*)data_,from,last_numb_read_);
  714.             offset = last_numb_read_;
  715.           }
  716.          else
  717.             {
  718.                long diff_minus = last_numb_read_ - (from_next - from);
  719.                if ( lseek(file_, -diff_minus, SEEK_CUR) == -1 )
  720.                 return traits::eof();
  721.                last_numb_read_ -= diff_minus;
  722.                offset = to_next - data_;
  723.             }
  724.         }
  725.  
  726.       delete [] from;
  727.     }
  728.         
  729.   if(last_numb_read_) 
  730.    {   
  731.      setg(data_, data_, data_+offset); 
  732.      setp(0, 0);
  733.      read_buff_=true;
  734.      return traits::to_int_type(*gptr());
  735.    }
  736.  
  737.   return traits::eof();
  738. }
  739.  
  740. /*
  741.  * pos_type seekoff(off_type, ios_base::seekdir, ios_base::openmode)
  742.  */
  743.  
  744. template<class charT, class traits>
  745. _TYPENAME basic_filebuf<charT, traits>::pos_type
  746. basic_filebuf<charT, traits>::seekoff(off_type off,
  747.                                       ios_base::seekdir way,ios_base::openmode)
  748. {
  749.   off_type            loff = off;
  750.   pos_type            newoff;
  751.  
  752.   if(file_ == -1)
  753.     return pos_type(off_type(-1));
  754.  
  755.   if ( (off == off_type(-1)) && (way==ios_base::beg) )
  756.     return pos_type(off_type(-1));
  757.  
  758.   if ( (way==ios_base::cur) && (off==off_type(0)) )
  759.   {
  760.      streamsize remain_in_buffer=0;
  761.      
  762.      if ( read_buff_ )
  763.       {
  764.         if ( gptr() )  
  765.           remain_in_buffer= egptr()-gptr();
  766.         else
  767.          {
  768.            if ( pptr() )  remain_in_buffer= epptr()-pptr();
  769.          }
  770.       }
  771.      else
  772.       if ( write_buff_ )
  773.         {
  774.           if ( pptr() )  
  775.            remain_in_buffer= -(pptr()-pbase());
  776.           else
  777.           { 
  778.            if ( gptr() )  remain_in_buffer= -(gptr()-eback());
  779.           }
  780.         }     
  781.  
  782.     int const_conv;
  783.  
  784.     #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  785.       const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  786.     #else
  787.       const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  788.     #endif
  789.       .encoding(); 
  790.  
  791.   if ( const_conv > 0 )
  792.    {
  793.     return ( (lseek(file_,0,SEEK_CUR)-remain_in_buffer*const_conv)/const_conv);
  794.    }
  795.   else
  796.    {  
  797.       streamsize relative_pos = gptr() - eback() + pptr() - pbase();
  798.  
  799.       pos_type position(relative_pos,absolute_pos,*state_beg); 
  800.       return position;       
  801.    }
  802.   } 
  803.  
  804.    if ( way==ios_base::cur )
  805.   {
  806.      int remain_in_buffer=0;
  807.  
  808.      if ( ((read_buff_) && !(write_buff_)) ||  ((read_buff_) && (write_buff_)) )
  809.       {
  810.         if ( pptr() )  remain_in_buffer= epptr()-pptr();
  811.         if ( gptr() )  remain_in_buffer= egptr()-gptr();
  812.       }
  813.      
  814.      if ( (write_buff_) && !(read_buff_) )
  815.         {
  816.           remain_in_buffer= 0;
  817.         }   
  818.  
  819.      loff-= remain_in_buffer;
  820.  
  821.   } 
  822.   
  823.     int const_conv;
  824.  
  825.     #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  826.       const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  827.     #else
  828.       const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  829.     #endif
  830.       .encoding(); 
  831.  
  832.    if ( const_conv < 1 )
  833.    {
  834.      if ( (way==ios_base::beg) && (off==off_type(0)) )
  835.      {
  836.         seekpos(0);
  837.      }
  838.      else 
  839.       return pos_type(off_type(-1));
  840.    }
  841.  
  842.  
  843.   if ( write_buff_)
  844.    {  
  845.       overflow( traits::eof() );
  846.       write_buff_ =false;  
  847.    }
  848.  
  849.   
  850.   int                 w = (way == ios_base::beg) ?
  851.                            SEEK_SET : ((way == ios_base::cur) ? SEEK_CUR :
  852.                                                           SEEK_END);  
  853.   newoff = lseek(file_, loff*const_conv, w);
  854.  
  855.   setp(0,0);
  856.   setg(0,0,0);
  857.  
  858.   return newoff;
  859. }
  860.  
  861. /*
  862.  * pos_type seekpos(pos_type, ios_base::openmode)
  863.  */
  864.  
  865. template<class charT, class traits>
  866. _TYPENAME basic_filebuf<charT, traits>::pos_type
  867. basic_filebuf<charT, traits>::
  868. seekpos(pos_type sp, ios_base::openmode which)
  869.    if(file_ == -1)
  870.     return pos_type(off_type(-1));
  871.  
  872.    if( sp == pos_type(off_type(-1)) )
  873.     return pos_type(off_type(-1)); 
  874.  
  875.    int const_conv;
  876.  
  877.     #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
  878.       const_conv = use_facet< codecvt<charT,char,state_t> >(this->getloc())
  879.     #else
  880.       const_conv = use_facet( this->getloc(), (codecvt<charT,char,state_t>* )0)
  881.     #endif
  882.       .encoding();
  883.  
  884.    if ( const_conv > 0 )
  885.       return seekoff(off_type(sp.offset()), ios_base::beg, which);
  886.  
  887.    _TYPENAME traits::off_type end_pos = lseek(file_,0,SEEK_END);
  888.    
  889.    if ( lseek(file_, sp.pos(), SEEK_SET) == -1 )
  890.     return pos_type(off_type(-1));
  891.  
  892.    setp(0,0);
  893.    setg(0,0,0); 
  894.  
  895.    *state_beg = *state_end = sp.state();
  896.  
  897.    if ( traits::eq_int_type(underflow(),traits::eof()) && (end_pos > sp.pos()))
  898.      return pos_type(off_type(-1));
  899.  
  900.    this->gbump(sp.offset());
  901.  
  902.    return sp;   
  903. }
  904.  
  905. /*
  906.  * int sync()
  907.  *
  908.  * this synchronizes the buffers and their streams
  909.  */
  910.  
  911. template<class charT, class traits>
  912. int basic_filebuf<charT, traits>::sync()
  913. {
  914.  if ( this->which_open_mode( ) & ios_base::out )
  915. {
  916.  if ( file_ == 1 )
  917.   {
  918.     if( traits::eq_int_type(overflow(traits::eof()),traits::eof()) ) 
  919.     return -1;
  920.   }
  921.  else
  922.   { 
  923.    pos_type p_out = seekoff(0,ios_base::cur,ios_base::out);
  924.    pos_type tmp_out = lseek(file_,0,SEEK_CUR);
  925.    pos_type end_out = lseek(file_,0,SEEK_END);
  926.    lseek(file_,tmp_out,SEEK_SET);
  927.    if ( end_out > p_out )
  928.     {
  929.       if( seekpos(p_out) == pos_type(off_type(-1)))
  930.        return -1;
  931.     }
  932.    else
  933.     {
  934.        if( traits::eq_int_type(overflow(traits::eof()),traits::eof()) )
  935.         return -1;
  936.     }
  937.   }
  938. }
  939.  
  940.  if ( this->which_open_mode( ) & ios_base::in )
  941.  {
  942.   if ( file_ != 0 )
  943.    {
  944.      pos_type p_in = seekoff(0,ios_base::cur,ios_base::in);
  945.      pos_type tmp_in = lseek(file_,0,SEEK_CUR);
  946.      pos_type end_in = lseek(file_,0,SEEK_END);
  947.      lseek(file_,tmp_in,SEEK_SET);
  948.    if ( end_in > p_in )
  949.     {
  950.       if( seekpos(p_in) == pos_type(off_type(-1)))
  951.        return -1;
  952.     }
  953.    }
  954.  }
  955.  
  956.   return 0;
  957. }
  958.  
  959.  
  960. /*
  961.  * streamsize xsputn(const char_type *, streamsize)
  962.  */
  963.  
  964. template<class charT, class traits>
  965. streamsize basic_filebuf<charT, traits>::
  966. xsputn(const char_type *s, streamsize n)
  967. {
  968.   if ( !s || (n == 0) ) return 0;
  969.  
  970.   if ( n >  __rwBufferSize )
  971.   {
  972.  
  973.    if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  974.     return 0;
  975.  
  976.    char_type   *eback_s = eback();
  977.    char_type   *gptr_s  = gptr();
  978.    char_type   *egptr_s = egptr();
  979.  
  980.    char_type   *pbase_s = pbase();
  981.    char_type   *pptr_s  = pptr();
  982.    char_type   *epptr_s = epptr();
  983.  
  984.    setg(0,0,0);
  985.    setp((char_type *)s,(char_type *)(s+n));
  986.    basic_streambuf<charT, traits>::pbump(n);
  987.  
  988.    if ( traits::eq_int_type(overflow( traits::eof() ),traits::eof()) )
  989.     return 0; 
  990.   
  991.    setg(eback_s,gptr_s,egptr_s);
  992.    setp(pbase_s,epptr_s);
  993.  
  994.    pbump(pptr_s-pbase_s); 
  995.  
  996.    return n;
  997.   }
  998.   else
  999.   {
  1000.     int         i=0;
  1001.  
  1002.     while((i < n) && ( !traits::eq_int_type(sputc(*s++),traits::eof())))
  1003.     i++;
  1004.  
  1005.     return i;
  1006.   }
  1007.  
  1008.  }
  1009.  
  1010.  
  1011.  
  1012. /*
  1013.  *
  1014.  * class basic_ifstream : public basic_istream
  1015.  *
  1016.  */
  1017.  
  1018. /*
  1019.  * basic_ifstream()
  1020.  */
  1021.  
  1022. template<class charT, class traits>
  1023. basic_ifstream<charT, traits>::basic_ifstream()
  1024. : basic_istream<charT, traits>( )
  1025. {
  1026.    init(&fb_);
  1027. }
  1028.  
  1029. /*
  1030.  * basic_ifstream(const char *, ios_base::openmode, long)
  1031.  *
  1032.  * opens a filebuf for (most likely) reading
  1033.  */
  1034.  
  1035. template<class charT, class traits>
  1036. basic_ifstream<charT, traits>::basic_ifstream(const char *s,
  1037.                                               ios_base::openmode mode,
  1038.                                               long protection )
  1039. : basic_istream<charT, traits>( )
  1040. {
  1041.   init(&fb_);
  1042.   open(s, mode, protection);
  1043. }
  1044.  
  1045. /*
  1046.  * basic_ifstream(int fd)
  1047.  *
  1048.  * opens a filebuf for reading
  1049.  */
  1050.  
  1051. template<class charT, class traits>
  1052. basic_ifstream<charT, traits>::
  1053. basic_ifstream(int fd)
  1054. : basic_istream<charT, traits>( )
  1055. {
  1056.  
  1057.   init(&fb_);
  1058.  
  1059.   if ( !fb_.open(fd) ) 
  1060.    this->setstate(ios_base::failbit);
  1061. }
  1062.  
  1063. /*
  1064.  * basic_ifstream(int fd, char_type *buf, int len)
  1065.  *
  1066.  * opens a filebuf for reading
  1067.  */
  1068.  
  1069. template<class charT, class traits>
  1070. basic_ifstream<charT, traits>::
  1071. basic_ifstream(int fd, char_type *buf, int len)
  1072. : basic_istream<charT, traits>( )
  1073. {
  1074.  
  1075.   init(&fb_);
  1076.  
  1077.   if ( ( buf!=0 ) && ( len>0 ) )
  1078.   fb_.pubsetbuf(buf,len);
  1079.  
  1080.   if ( !fb_.open(fd) ) 
  1081.    this->setstate(ios_base::failbit);
  1082. }
  1083.  
  1084.  
  1085. /*
  1086.  * ~basic_ifstream()
  1087.  */
  1088.  
  1089. template<class charT, class traits>
  1090. basic_ifstream<charT, traits>::~basic_ifstream()
  1091. {
  1092. }
  1093.  
  1094. /*
  1095.  * basic_filebuf *rdbuf() const
  1096.  *
  1097.  * returns the streambuf associated with this stream
  1098.  */
  1099.  
  1100. template<class charT, class traits>
  1101. basic_filebuf<charT, traits> *
  1102. basic_ifstream<charT, traits>::rdbuf() const
  1103. {
  1104.   return (basic_filebuf<charT, traits> *)&fb_;
  1105. }
  1106.  
  1107. /*
  1108.  * bool is_open()
  1109.  */
  1110.  
  1111. template<class charT, class traits>
  1112. bool basic_ifstream<charT, traits>::is_open()
  1113. {
  1114.   return fb_.is_open();
  1115. }
  1116.  
  1117. /*
  1118.  * void open(const char *, ios_base::openmode, long )
  1119.  *
  1120.  * opens up a file
  1121.  */
  1122.  
  1123. template<class charT, class traits>
  1124. void basic_ifstream<charT, traits>::open(const char *s,
  1125.                                          ios_base::openmode mode,
  1126.                                          long protection )
  1127. {
  1128.   mode |= ios_base::in; 
  1129.  
  1130.   if ( !fb_.open(s, mode, protection) )  
  1131.    this->setstate(ios_base::failbit);
  1132. }
  1133.  
  1134. /* 
  1135.  * void close()
  1136.  */
  1137.  
  1138. template<class charT, class traits>
  1139. void basic_ifstream<charT, traits>::close()
  1140. {
  1141.   if(!is_open())
  1142.     return;
  1143.   
  1144.   if(!fb_.close())
  1145.     this->setstate(ios_base::failbit);
  1146. }
  1147.  
  1148.  
  1149. /*
  1150.  *
  1151.  * class basic_ofstream : public basic_ostream
  1152.  *
  1153.  */
  1154.  
  1155. /*
  1156.  * basic_ofstream()
  1157.  */
  1158.  
  1159. template<class charT, class traits>
  1160. basic_ofstream<charT, traits>::basic_ofstream()
  1161. : basic_ostream<charT, traits>( )
  1162. {
  1163.    init(&fb_);
  1164. }
  1165.  
  1166. /*
  1167.  * basic_ofstream(const char *, ios_base::openmode, long )
  1168.  */
  1169.  
  1170. template<class charT, class traits>
  1171. basic_ofstream<charT, traits>::
  1172. basic_ofstream(const char *s, ios_base::openmode mode, long protection)
  1173. : basic_ostream<charT, traits>()
  1174. {
  1175.        
  1176.   init(&fb_);
  1177.   open(s, mode, protection);
  1178. }
  1179.  
  1180. /*
  1181.  * basic_ofstream(int fd)
  1182.  *
  1183.  * opens a filebuf for writing
  1184.  */
  1185.  
  1186. template<class charT, class traits>
  1187. basic_ofstream<charT, traits>::
  1188. basic_ofstream(int fd)
  1189. : basic_ostream<charT, traits>( )
  1190. {
  1191.  
  1192.   init(&fb_);
  1193.  
  1194.   if ( !fb_.open(fd) ) 
  1195.    this->setstate(ios_base::failbit);
  1196. }
  1197.  
  1198. /*
  1199.  * basic_ofstream(int fd, char_type *buf, int len)
  1200.  *
  1201.  * opens a filebuf for writing
  1202.  */
  1203.  
  1204. template<class charT, class traits>
  1205. basic_ofstream<charT, traits>::
  1206. basic_ofstream(int fd, char_type *buf, int len)
  1207. : basic_ostream<charT, traits>( )
  1208. {
  1209.  
  1210.   init(&fb_);
  1211.  
  1212.   if ( ( buf!=0 ) && ( len>0 ) )
  1213.   fb_.pubsetbuf(buf,len);
  1214.  
  1215.   if ( !fb_.open(fd) ) 
  1216.    this->setstate(ios_base::failbit);
  1217. }
  1218.  
  1219.  
  1220. /*
  1221.  * ~basic_ofstream()
  1222.  */
  1223.  
  1224. template<class charT, class traits>
  1225. basic_ofstream<charT, traits>::~basic_ofstream()
  1226. {
  1227. }
  1228.  
  1229. /*
  1230.  * basic_filebuf *rdbuf() const
  1231.  */
  1232.  
  1233. template<class charT, class traits>
  1234. basic_filebuf<charT, traits> *
  1235. basic_ofstream<charT, traits>::rdbuf() const
  1236. {
  1237.   return (basic_filebuf<charT, traits> *)&fb_;
  1238. }
  1239.  
  1240. /*
  1241.  * bool is_open()
  1242.  */
  1243.  
  1244. template<class charT, class traits>
  1245. bool basic_ofstream<charT, traits>::is_open()
  1246. {
  1247.   return fb_.is_open();
  1248. }
  1249.  
  1250. /*
  1251.  * void open(const char *, ios_base::openmode)
  1252.  */
  1253.  
  1254. template<class charT, class traits>
  1255. void basic_ofstream<charT, traits>::open(const char *s,
  1256.                                          ios_base::openmode mode,
  1257.                                          long protection )
  1258. {
  1259.   mode |= ios_base::out;
  1260.  
  1261.   if ( !fb_.open(s, mode, protection) )
  1262.    this->setstate(ios_base::failbit);
  1263. }
  1264.  
  1265. /*
  1266.  * void close()
  1267.  */
  1268.  
  1269. template<class charT, class traits>
  1270. void basic_ofstream<charT, traits>::close()
  1271. {
  1272.   if(!is_open())
  1273.     return;
  1274.  
  1275.   if(!fb_.close())
  1276.     this->setstate(ios_base::failbit);
  1277. }
  1278.  
  1279. /*
  1280.  *
  1281.  * class basic_fstream : public basic_iostream
  1282.  *
  1283.  */
  1284.  
  1285. /*
  1286.  * basic_fstream()
  1287.  */
  1288.  
  1289. template<class charT, class traits>
  1290. basic_fstream<charT, traits>::basic_fstream()
  1291. : basic_iostream<charT, traits>( )
  1292. {
  1293.    init(&fb_);
  1294. }
  1295.  
  1296. /*
  1297.  * basic_fstream(const char *, ios_base::openmode, long)
  1298.  *
  1299.  * opens a filebuf for reading and writing
  1300.  */
  1301.  
  1302. template<class charT, class traits>
  1303. basic_fstream<charT, traits>::
  1304. basic_fstream(const char *s, ios_base::openmode mode, long protection)
  1305. : basic_iostream<charT, traits>( )
  1306. {
  1307.   init(&fb_);
  1308.   open(s, mode, protection);
  1309. }
  1310.  
  1311. /*
  1312.  * basic_fstream(int fd)
  1313.  *
  1314.  * opens a filebuf for reading and writing
  1315.  */
  1316.  
  1317. template<class charT, class traits>
  1318. basic_fstream<charT, traits>::
  1319. basic_fstream(int fd)
  1320. : basic_iostream<charT, traits>( )
  1321. {
  1322.  
  1323.   init(&fb_);
  1324.  
  1325.   if ( !fb_.open(fd) ) 
  1326.    this->setstate(ios_base::failbit);
  1327. }
  1328.  
  1329. /*
  1330.  * basic_fstream(int fd, char_type *buf, int len)
  1331.  *
  1332.  * opens a filebuf for reading and writing
  1333.  */
  1334.  
  1335. template<class charT, class traits>
  1336. basic_fstream<charT, traits>::
  1337. basic_fstream(int fd, char_type *buf, int len)
  1338. : basic_iostream<charT, traits>( )
  1339. {
  1340.  
  1341.   init(&fb_);
  1342.  
  1343.   if ( ( buf!=0 ) && ( len>0 ) )
  1344.   fb_.pubsetbuf(buf,len);
  1345.  
  1346.   if ( !fb_.open(fd) ) 
  1347.    this->setstate(ios_base::failbit);
  1348. }
  1349.  
  1350.  
  1351. /*
  1352.  * ~basic_fstream()
  1353.  */
  1354.  
  1355. template<class charT, class traits>
  1356. basic_fstream<charT, traits>::~basic_fstream()
  1357. {
  1358. }
  1359.  
  1360. /*
  1361.  * basic_filebuf *rdbuf() const
  1362.  *
  1363.  * returns the streambuf associated with this stream
  1364.  */
  1365.  
  1366. template<class charT, class traits>
  1367. basic_filebuf<charT, traits> *
  1368. basic_fstream<charT, traits>::rdbuf() const
  1369. {
  1370.   return (basic_filebuf<charT, traits> *)&fb_;
  1371. }
  1372.  
  1373. /*
  1374.  * bool is_open()
  1375.  */
  1376.  
  1377. template<class charT, class traits>
  1378. bool basic_fstream<charT, traits>::is_open()
  1379. {
  1380.   return fb_.is_open();
  1381. }
  1382.  
  1383. /*
  1384.  * void open(const char *, ios_base::openmode, long)
  1385.  *
  1386.  * opens up a file
  1387.  */
  1388.  
  1389. template<class charT, class traits>
  1390. void basic_fstream<charT, traits>::
  1391. open(const char *s, ios_base::openmode mode, long protection)
  1392. {
  1393.   mode = mode | ios_base::in | ios_base::out;
  1394.   if ( !fb_.open(s, mode, protection) ) 
  1395.    this->setstate(ios_base::failbit);
  1396. }
  1397.  
  1398. /* 
  1399.  * void close()
  1400.  */
  1401.  
  1402. template<class charT, class traits>
  1403. void basic_fstream<charT, traits>::close()
  1404. {
  1405.   if(!is_open())
  1406.     return;
  1407.   
  1408.   if(!fb_.close())
  1409.     this->setstate(ios_base::failbit);
  1410. }
  1411.  
  1412. #ifndef _RWSTD_NO_NAMESPACE
  1413. }
  1414. #endif
  1415.  
  1416. #pragma option pop
  1417. #endif /* __FSTREAM_CC */
  1418.